﻿#region 命名空间
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
#endregion

namespace ContentFactory
{
    /// <summary>
    /// 提供系统文件（夹）的图标。
    /// </summary>
    public static class IconManager
    {
        #region SHFILEINFO

        [StructLayout(LayoutKind.Sequential)]
        public struct SHFILEINFO
        {
            public IntPtr hIcon;
            public IntPtr iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        }

        #endregion

        #region SHGFI

        public enum SHGFI
        {
            SHGFI_ICON = 0x100,
            SHGFI_LARGEICON = 0x0,
            SHGFI_USEFILEATTRIBUTES = 0x10
        }

        #endregion

        #region 字段

        static ImageSource directoryIcon;
        static readonly Dictionary<string, ImageSource> fileIcons;

        #endregion

        #region 初始化

        /// <summary>
        /// 初始化。
        /// </summary>
        static IconManager()
        {
            fileIcons = new Dictionary<string, ImageSource>();
        }

        #endregion

        #region 方法

        /// <summary>   
        /// 返回系统设置的图标。  
        /// </summary>
        [DllImport("shell32.dll")]
        public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

        /// <summary>   
        /// 获取文件图标。
        /// </summary>
        public static ImageSource GetFileIcon(string fileName)
        {
            string extension = Path.GetExtension(fileName).ToUpper();
            if (fileIcons.ContainsKey(extension))
            {
                return fileIcons[extension];
            }
            else
            {
                SHFILEINFO info = new SHFILEINFO();
                IntPtr intPtr = SHGetFileInfo(fileName, 0, ref info, (uint)Marshal.SizeOf(info), (uint)(SHGFI.SHGFI_ICON | SHGFI.SHGFI_LARGEICON | SHGFI.SHGFI_USEFILEATTRIBUTES));
                if (intPtr.Equals(IntPtr.Zero)) return null;
                Icon icon = Icon.FromHandle(info.hIcon);
                ImageSource image = ToImage(icon);
                fileIcons.Add(extension, image);
                return image;
            }
        }

        /// <summary>   
        /// 获取文件夹图标。
        /// </summary>
        public static ImageSource GetDirectoryIcon()
        {
            if (directoryIcon == null)
            {
                SHFILEINFO info = new SHFILEINFO();
                IntPtr intPtr = SHGetFileInfo(@"", 0, ref info, (uint)Marshal.SizeOf(info), (uint)(SHGFI.SHGFI_ICON | SHGFI.SHGFI_LARGEICON));
                if (intPtr.Equals(IntPtr.Zero)) return null;
                Icon icon = Icon.FromHandle(info.hIcon);
                directoryIcon = ToImage(icon);
            }
            return directoryIcon;
        }

        /// <summary>   
        /// 将 Icon 对象转换成 ImageSource 对象。
        /// </summary>
        static ImageSource ToImage(Icon icon)
        {
            Bitmap bitmap = icon.ToBitmap();
            IntPtr intPtr = bitmap.GetHbitmap();
            ImageSource image = Imaging.CreateBitmapSourceFromHBitmap(intPtr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            return image;
        }

        #endregion
    }
}
